package com.telnetnz.ticketdesk.action.ticket;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.rockbb.common.simpleframe.config.SimpleConfig;
import com.rockbb.common.sso.session.SessionConstants;
import com.rockbb.common.utilities.text.ComponentBuilder;
import com.rockbb.common.utilities.text.StringUtils;
import com.rockbb.common.utilities.time.TimeUtil;
import com.telnetnz.ticketdesk.action.base.BasicSessionPageAccAction;
import com.telnetnz.ticketdesk.action.common.CommonUtils;
import com.telnetnz.ticketdesk.bean.Project;
import com.telnetnz.ticketdesk.bean.ProjectToUser;
import com.telnetnz.ticketdesk.bean.Ticket;
import com.telnetnz.ticketdesk.service.ProjectService;
import com.telnetnz.ticketdesk.service.ProjectToUserService;
import com.telnetnz.ticketdesk.service.TagService;
import com.telnetnz.ticketdesk.service.TicketService;
import com.telnetnz.ticketdesk.service.UserService;

public class TicketListAction extends BasicSessionPageAccAction
{
	private static Logger logger = Logger.getLogger(TicketListAction.class);

	public String doView()
	{
		RequestBean bean = new DefaultRequestBean();
		long id = bean.getLong("id", 0L);
		Ticket ticket = TicketService.getTicket(id);
		if (ticket == null)
			return this.message_box(
					langRes.get("global.error"),
					langRes.get("ticket.ticket-not-exist-redirect", new String[]{bean.getRedirect()}),
					bean.getRedirect(),
					2);
		else if (!isSuperSession() && !ticket.isViewable(getSession().getSession_uuid()))
			return this.message_box(
					langRes.get("global.no-permission"),
					langRes.get("global.no-permission-redirect", new String[]{bean.getRedirect()}),
					bean.getRedirect(),
					2);

		if (isSuperSession() || ticket.isEditable(getSession().getSession_uuid()))
			this.put_page_key("edit_button", 1);

		this.put_page_key("ticket", ticket);
		this.put_page_key("project_to_user", ProjectToUserService.getProjectToUser(ticket.getProjectId(), getSession().getSession_uuid()));

		this.put_page_key("owner_options", CommonUtils.buildUserDropdown(
				UserService.getByProject(ticket.getProjectId(), 0L),
				ticket.getOwnerId(), 
				false));

		this.put_page_key("project_options", CommonUtils.buildProjectDropdown(
				ProjectService.getByPageAndCondition(0, 100, ProjectService.ORDERBY_NAME, 1, null), 
				ticket.getProjectId(), 
				false));
		this.put_page_key("type_options", CommonUtils.buildSingleDropdown(langRes, "ticket.type.", TicketService.TYPES, ticket.getType(), false));
		this.put_page_key("priority_options", CommonUtils.buildSingleDropdown(langRes, "ticket.priority.", TicketService.PRIORITIES, ticket.getPriority(), false));
		this.put_page_key("status_options", CommonUtils.buildSingleDropdown(langRes, "ticket.status.", TicketService.STATUSES, ticket.getStatus(), false));

		this.put_js_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.min.js",
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui-timepicker-addon.js",
				SimpleConfig.getConfig("static_file_url")+"/js/tiny_mce/tiny_mce.js"});

		this.put_css_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.css"});

		return SUCCESS;
	}

	public String doList()
	{
		ListRequestBean bean = new ListRequestBean();

		List<Long> ownerIds = new ArrayList<Long>();
		if (bean.getOwnerId() > 0L)
			ownerIds.add(bean.getOwnerId());

		List<ProjectToUser> projectToUsers = ProjectToUserService.getByUserId(getSession().getSession_uuid());
		List<Integer> projectIds = new ArrayList<Integer>(); // The ids for building the drop down list
		List<Integer> includedProjectIds = new ArrayList<Integer>(); // The ids to be put into sql query
		if (isSuperSession())
		{
			// In a super session, show the tickets in all projects
			List<Project> projects = ProjectService.getByPageAndCondition(0, 100, ProjectService.ORDERBY_NAME, 1, null);
			for (Project project : projects)
			{
				projectIds.add(project.getId());
				if (bean.getProjectId() == 0 || bean.getProjectId() == project.getId())
				{
					includedProjectIds.add(project.getId());
				}
			}
		}
		else
		{
			// A hack to prevent the full list being displayed to a user associated with no projects.
			includedProjectIds.add(-1);
			for (ProjectToUser projectToUser : projectToUsers)
			{
				projectIds.add(projectToUser.getProjectId());
				// If no projectId is specified, all associated project ids will be added. Otherwise, only the allowed id will be added.
				if (bean.getProjectId() == 0 || bean.getProjectId() == projectToUser.getProjectId()) 
				{
					includedProjectIds.add(projectToUser.getProjectId());
				}
			}
		}
		
		

		List<Integer> statuses = new ArrayList<Integer>();
		if (bean.getStatus() > -1) statuses.add(bean.getStatus());

		List<Integer> excludedStatuses = new ArrayList<Integer>();
		if (bean.getShowClosed() == 0) {
			excludedStatuses.add(TicketService.STATUS_CLOSED);
			excludedStatuses.add(TicketService.STATUS_CANCELED);
		}

		long size = TicketService.countByCondition(
				includedProjectIds, 
				(bean.getProjectId() == 0)? getSession().getSession_uuid() : 0L, 
				0L, 
				ownerIds, 
				bean.getCreatorId(), 
				0L, 
				bean.getSubject(), 
				null, 
				bean.getPriority(), 
				bean.getType(), 
				statuses, 
				excludedStatuses, 
				bean.getTagId(), 
				null, 
				null, 
				bean.getCreateAfter(), 
				bean.getCreateBefore(), 
				null, 
				null);
		bean.setSize(size);

		List<Ticket> tickets = TicketService.getByPageAndCondition(
				bean.getStart(), 
				bean.getStep(), 
				bean.getOrderby(), 
				bean.getOrder(), 
				includedProjectIds, 
				(bean.getProjectId() == 0)? getSession().getSession_uuid() : 0L, 
				0L, 
				ownerIds, 
				bean.getCreatorId(), 
				0L, 
				bean.getSubject(), 
				null, 
				bean.getPriority(), 
				bean.getType(), 
				statuses, 
				excludedStatuses, 
				bean.getTagId(), 
				null, 
				null, 
				bean.getCreateAfter(), 
				bean.getCreateBefore(), 
				null, 
				null);

		String page_nav = ComponentBuilder.generate_pagination(
				baseLink() + bean.getParams() + bean.getOrderParams(), 
				"start", 
				bean.getSize(), 
				bean.getStep(),
				bean.getStart(), 
				false, 
				"");

		put_page_key("tickets", tickets);
		put_page_key("bean", bean);
		put_page_key("page_nav", page_nav);

		this.put_page_key("creator_options", CommonUtils.buildUserDropdown(
				UserService.getByPageAndCondition(
						0, 
						100, 
						UserService.ORDER_BY_NAME, 
						1, 
						SessionConstants.USER_ID_ANONYMOUS, 
						null, 
						null), 
				bean.getCreatorId(), 
				true));

		this.put_page_key("owner_options", CommonUtils.buildUserDropdown(
				UserService.getByPageAndCondition(
						0, 
						100, 
						UserService.ORDER_BY_NAME, 
						1, 
						SessionConstants.USER_ID_ANONYMOUS, 
						null, 
						null), 
				bean.getOwnerId(), 
				true));

		this.put_page_key("project_options", CommonUtils.buildProjectDropdown(ProjectService.getProjects(projectIds), bean.getProjectId(), true));
		this.put_page_key("type_options", CommonUtils.buildSingleDropdown(langRes, "ticket.type.", TicketService.TYPES, bean.getType(), true));
		this.put_page_key("priority_options", CommonUtils.buildSingleDropdown(langRes, "ticket.priority.", TicketService.PRIORITIES, bean.getPriority(), true));
		this.put_page_key("orderby_options", CommonUtils.buildOrderByDropdown(langRes, "ticket.orderby.", TicketService.ORDER_BY, bean.getOrderby()));
		this.put_page_key("order_options", CommonUtils.buildOrderDropdown(langRes, "global.order.", TicketService.ORDER, bean.getOrder()));
		this.put_page_key("status_options", CommonUtils.buildSingleDropdown(langRes, "ticket.status.", TicketService.STATUSES, bean.getStatus(), true));
		this.put_page_key("tag_options", CommonUtils.buildTagDropdown(TagService.getAllTags(), bean.getTagId(), true));
		this.put_page_key("post_action", baseLink());
		this.put_js_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.min.js",
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui-timepicker-addon.js"
				});

		this.put_css_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.css"});

		return SUCCESS;
	}

	public class ListRequestBean extends RequestBean
	{
		private int start;
		private int step;
		private int orderby;
		private int order;
		private int projectId;
		private long ownerId;
		private String subject;
		private int priority;
		private int type;
		private int status;
		private int showClosed;
		private long tagId;
		private long creatorId;
		private Date createAfter;
		private Date createBefore;
		private long size;
		private String params;
		private String orderParams;

		public int getStart() {
			return start;
		}

		public int getStep() {
			return step;
		}

		public int getOrderby() {
			return orderby;
		}

		public int getOrder() {
			return order;
		}

		public int getProjectId() {
			return projectId;
		}

		public long getOwnerId() {
			return ownerId;
		}

		public String getSubject() {
			return subject;
		}

		public int getPriority() {
			return priority;
		}

		public int getType() {
			return type;
		}

		public int getShowClosed() {
			return showClosed;
		}

		public long getTagId() {
			return tagId;
		}

		public long getCreatorId() {
			return creatorId;
		}

		public Date getCreateAfter() {
			return createAfter;
		}

		public Date getCreateBefore() {
			return createBefore;
		}

		public int getStatus() {
			return status;
		}

		public long getSize() {
			return size;
		}

		public void setSize(long size) {
			this.size = size;
		}

		public String getParams() {
			return params;
		}

		public String getOrderParams() {
			return orderParams;
		}

		@Override
		protected void loadRequest() 
		{
			start = getInt("start");
			step = getInt("step", 20);
			orderby = getInt("orderby");
			order = getInt("order");
			projectId = getInt("project_id");
			ownerId = getLong("owner_id", 0L);
			subject = getUnicode("subject", SimpleConfig.getConfig("encoding"));
			priority = getInt("priority", -1);
			type = getInt("type", -1);
			status = getInt("status", -1);
			showClosed = getInt("show_closed");
			tagId = getLong("tag_id", 0);
			creatorId = getLong("creator_id", 0L);
			if (get("create_before").length() > 0) 
				createBefore = TimeUtil.getDate(get("create_before"),"yyyy-MM-dd");
			if (get("create_after").length() > 0) 
				createAfter = TimeUtil.getDate(get("create_after"),"yyyy-MM-dd");

			List<String[]> nv_pairs = new ArrayList<String[]>();
			nv_pairs.add(new String[]{"step", step+""});
			if (projectId > 0)
				nv_pairs.add(new String[]{"project_id", projectId+""});
			if (ownerId > 0)
				nv_pairs.add(new String[]{"owner_id", ownerId+""});
			if (subject.length() > 0)
				nv_pairs.add(new String[]{"subject", subject});
			if (priority > -1)
				nv_pairs.add(new String[]{"priority", priority+""});
			if (type > -1)
				nv_pairs.add(new String[]{"type", type+""});
			if (showClosed > 0)
				nv_pairs.add(new String[]{"show_closed", showClosed+""});
			if (status > -1)
				nv_pairs.add(new String[]{"status", status+""});
			if (tagId > 0L)
				nv_pairs.add(new String[]{"tag_id", tagId+""});
			if (creatorId > 0L)
				nv_pairs.add(new String[]{"creator_id", creatorId+""});
			if (createAfter != null)
				nv_pairs.add(new String[]{"create_after", get("create_after")});
			if (createBefore != null)
				nv_pairs.add(new String[]{"create_before", get("create_before")});

			params = StringUtils.appendParametersToURL("", nv_pairs, SimpleConfig.getConfig("encoding"));
			orderParams = "&orderby=" + orderby +"&order=" + order;
		}

		@Override
		protected boolean validate() 
		{
			// TODO Auto-generated method stub
			return false;
		}
	}
}
